package com.dapeis.web.wx.controller.impl;

import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSON;

import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

import com.ag.core.base.Pager;
import com.ag.core.exception.InvalidParamException;
import com.ag.core.exception.SysTipsException;
import com.ag.core.exception.VisitLimitException;
import com.ag.core.utils.AgAssert;
import com.ag.dao.PagerHelper;
import com.ag.utils.DateUtils;
import com.ag.utils.NumberUtils;
import com.ag.utils.json.AGsonBuilder;
import com.ag.utils.json.GsonUtils;
import com.dapeis.core.convert.pager.OrderPagerSearchConvertCriteria;
import com.dapeis.core.utils.DBConfigUtils;
import com.dapeis.core.utils.RequirementConfig;
import com.dapeis.core.utils.StringUtil;
import com.dapeis.core.utils.StylistConstants;
import com.dapeis.domain.Coupons;
import com.dapeis.domain.Order;
import com.dapeis.domain.Requirement;
import com.dapeis.domain.ext.OrderExt;
import com.dapeis.pay.swiftpass.util.SPPayUtil;
import com.dapeis.service.CouponsService;
import com.dapeis.service.OrderService;
import com.dapeis.service.RequirementService;
import com.dapeis.service.order.OrderFlow;
import com.dapeis.web.wx.controller.IOrderController;
import com.dapeis.web.wx.controller.RestController;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

/**
 * 
 * Title:OrderImplController.java OrderImplController Description:
 * 
 * @author yuanyong
 * @date 2017年5月4日 下午5:00:41 Email: hzyuanyong@126.com
 *
 */
@Controller
@RequestMapping("/wx/order")
public class OrderImplController extends RestController implements
	IOrderController {
    @Resource
    OrderService orderService;
    @Resource
    RequirementService requirementService;
    @Resource
    CouponsService couponsService;

    @Override
    public @ResponseBody JsonElement queryCouponsOrder(
	    @RequestParam Long orderId, HttpServletRequest request) {
	Order order = orderService.selectByPrimaryKey(orderId);
	AgAssert.notNull(order, SysTipsException.class, "查询不到订单信息:" + orderId);
	AgAssert.isTrue(order.getUserId() == getThreadLocalUserId(),
		SysTipsException.class, "不能操作别人的需求");
	// OrderFlow orderFlow = orderService.getFlow(order.getType());
	// orderFlow.check(order, StylistConstants.Order.Status.WAIT_PAY);

	Requirement requirement = requirementService.selectByPrimaryKey(order
		.getLinkId());
	AgAssert.notNull(requirement, SysTipsException.class, "非法订单信息!");

	JsonObject json = success();
	JsonObject elementJson = new JsonObject();
	elementJson.addProperty("orderId", order.getId().toString());
	elementJson.addProperty("price",
		getRequirementOriginalPrice(requirement.getType()));
	elementJson.addProperty("requiremntTypeName", DBConfigUtils
		.getTypeNameForMoneyLog(requirement.getType()).concat("服务"));
	elementJson.addProperty("requirementType", requirement.getType());
	elementJson.addProperty("createTime", DateUtils.format(
		DateUtils.YYYY_MM_DD_HH_MM_SS,
		new Date(requirement.getCreateTime() * 1000)));
	if (requirement.getType() == RequirementConfig.Type.CONSULTING) {
	    elementJson
		    .add("coupons",
			    AGsonBuilder
				    .create()
				    .toJsonTree(
					    couponsService
						    .getMyCouponsNormal(getThreadLocalUserId())));
	} else {
	    // 兼容前端
	    elementJson.add("coupons",
		    AGsonBuilder.create().toJsonTree(new String[0]));
	}
	json.add("data", AGsonBuilder.create().toJsonTree(elementJson));
	return json;
    }

    @Override
    public JsonElement updateCouponsOrder(@RequestParam Long orderId,
	    @RequestParam(required = false) Integer couponsId,
	    HttpServletRequest request) {
	Order order = orderService.selectByPrimaryKey(orderId);
	AgAssert.notNull(order, SysTipsException.class, "查询不到订单信息：" + orderId);
	AgAssert.isTrue(order.getUserId() == getThreadLocalUserId(),
		SysTipsException.class, "不能操作别人的订单");
	OrderFlow orderFlow = orderService.getFlow(order.getType());
	orderFlow.check(order, StylistConstants.Order.Status.WAIT_PAY);
	Requirement requirement = requirementService.selectByPrimaryKey(order
		.getLinkId());
	AgAssert.notNull(requirement, SysTipsException.class, "非法订单信息!");
	if (requirement.getType() == RequirementConfig.Type.CONSULTING
		&& NumberUtils.isValid(couponsId)) {
	    // 咨询订单且有优惠券信息
	    order = orderService.updateOrder(order, couponsId);
	}
	JsonObject json = success();
	if (null != order.getCouponsId() && order.getTransactionPrice() == 0) {
	    // 使用了优惠券且支付价格为0
	    json.add("payInfo", AGsonBuilder.create().toJsonTree(new Object()));
	    json.addProperty("goPay", "0");
	} else {
	    Map resultMap = orderService.createUnified(request, order,
		    getThreadLocalUser());
	    if (SPPayUtil.checkResut(resultMap)) {// 成功
		String pay_info = resultMap.get("pay_info").toString();
		order.setUnifiedTime(new Date().getTime() / 1000);
		order.setPayInfoExt(pay_info);
		orderService.updateByPrimaryKeySelective(order);
		json.addProperty("goPay", "1");
		json.add("payInfo", GsonUtils.parse(pay_info));
	    } else {
		throw new InvalidParamException(
			SPPayUtil.getResultMsg(resultMap));
	    }
	}
	json.addProperty("price",
		DBConfigUtils.paserMoney(order.getTransactionPrice()));
	json.addProperty("userInfo",
		getThreadLocalUser().getInfoId() == null ? "0" : "1");
	return json;
    }

    @Override
    public JsonElement getUnifiedInfo(@RequestParam Long orderId,
	    HttpServletRequest request) {
	Order order = orderService.selectByPrimaryKey(orderId);
	AgAssert.notNull(order, SysTipsException.class, "无法查询订单:" + orderId);
	OrderFlow orderFlow = orderService.getFlow(order.getType());
	orderFlow.check(order, StylistConstants.Order.Status.WAIT_PAY);
	AgAssert.isTrue(getThreadLocalUserId() == order.getUserId(),
		SysTipsException.class, "无权操作别人的订单!");
	String pay_info = "";
	Map resultMap = null;
	// if (StringUtil.isBlank(order.getPayInfoExt())) {
	resultMap = orderService.createUnified(request, order,
		getThreadLocalUser());
	if (SPPayUtil.checkResut(resultMap)) {// 成功
	    pay_info = resultMap.get("pay_info").toString();
	    order.setUnifiedTime(new Date().getTime() / 1000);
	    order.setPayInfoExt(pay_info);
	    orderService.updateByPrimaryKeySelective(order);
	} else {
	    throw new InvalidParamException(SPPayUtil.getResultMsg(resultMap));
	}
	// } else {
	// pay_info = order.getPayInfoExt();
	// }

	JsonObject json = success();
	json.add("payInfo", GsonUtils.parse(pay_info));
	json.addProperty("price",
		getRequirementOriginalPrice(order.getOriginalPrice()));
	json.addProperty("userInfo",
		getThreadLocalUser().getInfoId() == null ? "0" : "1");
	return json;

    }

    @Override
    public @ResponseBody JsonElement getPayResult(@RequestParam Long orderId,
	    HttpServletRequest request) {
	Order order = orderService.selectByPrimaryKey(orderId);
	AgAssert.notNull(order, SysTipsException.class, "查询不到订单信息:" + orderId);
	OrderFlow orderFlow = orderService.getFlow(order.getType());
	orderFlow.check(order, StylistConstants.Order.Status.WAIT_PAY);
	Map resultMap = orderService.queryOrder(request, order);
	if (SPPayUtil.checkPayResult(resultMap)) {// 支付成功
	    // 获取订单号：
	    String out_trand_no = resultMap
		    .get(SPPayUtil.PROPERTY_OUT_TRADE_NO).toString();
	    Long dborderId = new Long(out_trand_no);
	    Order dborder = orderService.selectForLock(dborderId);
	    String total_fee = resultMap.get(SPPayUtil.PROPERTY_PAY_TOTAL_FEE)
		    .toString();
	    if (null != dborder
		    && dborder.getOriginalPrice().toString().equals(total_fee)) {
		if (order.getPayState() == StylistConstants.Order.PayStatus.WAIT_PAY) {
		    order.setPayState(StylistConstants.Order.PayStatus.PAY_SUCCESS);
		    order.setPayTime(new Date().getTime() / 1000);
		    order.setState(StylistConstants.Order.Status.PAY_SUCCESS);
		    orderService.updateByPrimaryKeySelective(order);
		    logger.info("SP通知的，订单状态更新成功,已经支付了..");
		}
		JsonObject json = success();
		return json;

	    } else {
		logger.info("out_trad_no from sp_server is not exits!");
	    }

	}
	throw new InvalidParamException(SPPayUtil.getCode(resultMap),
		SPPayUtil.getResultMsg(resultMap));
    }

    @Override
    public @ResponseBody JsonElement getMyOrder(HttpServletRequest request) {
	// 暂时不用分页
	Pager pager = new Pager();
	pager.init(OrderExt.class, new OrderPagerSearchConvertCriteria());
	Example example = new Example(OrderExt.class);
	Criteria criteria = example.createCriteria();
	criteria.andEqualTo(Order.PROPERTY_USERID, getThreadLocalUserId());
	criteria.andEqualTo(Order.PROPERTY_TYPE,
		StylistConstants.Order.Type.REQUIREMENT);
	example.orderBy(Order.PROPERTY_STATE).desc();
	pager.setExample(example);
	pager.setPageSize(999);// 默认不分页
	orderService.pager(pager);
	PagerHelper.pager(pager, orderService.getOrderExtMapper());
	orderService.doQueryOrderRefundResult(pager);
	List<OrderExt> list = pager.getItemList();
	JsonObject json = success();
	JsonArray jsonArray = new JsonArray();
	if (!list.isEmpty()) {
	    for (OrderExt orderExt : list) {
		JsonObject jo = new JsonObject();
		jo.addProperty("title", RequirementConfig.getTypeName(orderExt
			.getRequirement().getType()));
		jo.addProperty("time", DateUtils.format(
			DateUtils.YYYY_MM_DD_HH_MM_SS,
			new Date(orderExt.getRecordCreateTime() * 1000)));
		jo.addProperty("status",
			StylistConstants.getOrderStatusStr(orderExt));
		jo.addProperty("orderId", orderExt.getId().toString());
		jsonArray.add(jo);
	    }
	}
	json.add("list", jsonArray);
	return json;
    }

    @Override
    public JsonElement detail(@RequestParam Long orderId,
	    HttpServletRequest request) {
	OrderExt orderExt = orderService.getOrderExtMapper()
		.selectByPrimaryKey(orderId);
	AgAssert.notNull(orderExt, SysTipsException.class, "查询不到订单 orderId:"
		+ orderId);
	AgAssert.isTrue(orderExt.getUserId() == getThreadLocalUserId(),
		SysTipsException.class, "无权查看.");

	JsonObject json = success();
	// 该用户请求过预支付
	String payInfo = orderExt.getPayInfoExt();
	// 未请求预支付(1,以使用优惠券，2.未使用优惠券，但该用户名下没有优惠券)
	List<Coupons> coupons = couponsService
		.getMyCouponsNormal(getThreadLocalUserId());
	// 1直接去调用预付款信息,0 到选择优惠券页面
	String payStauas = "1";
	if (StringUtil.isBlank(payInfo)
		&& !coupons.isEmpty()
		&& orderExt.getRequirement().getType() == RequirementConfig.Type.CONSULTING) {
	    payStauas = "0";
	}
	json.addProperty("toPay", payStauas);
	json.addProperty("userId", getThreadLocalUserId());
	json.addProperty("couponsCode", StringUtil.isBlank(getThreadLocalUser()
		.getCouponsCode()) ? new String() : getThreadLocalUser()
		.getCouponsCode());
	json.add("requirement",
		AGsonBuilder.create().toJsonTree(orderExt.getRequirement()));
	json.add("order",
		AGsonBuilder.create().toJsonTree(orderExt, Order.class)
			.getAsJsonObject());
	json.add("comment",
		AGsonBuilder.create().toJsonTree(orderExt.getComment()));
	json.add("collocation",
		AGsonBuilder.create().toJsonTree(orderExt.getCollocation()));
	return json;
    }

    public String getRequirementOriginalPrice(Integer price) {
	DecimalFormat decimalFormat = new DecimalFormat("0.00");
	Float priceFloat = new Float(price);
	String pasStr = decimalFormat.format(priceFloat / 100);
	return pasStr;
    }

    @Override
    public JsonElement canel(@RequestParam Long orderId,
	    HttpServletRequest request) {
	Order order = orderService.selectByPrimaryKey(orderId);
	AgAssert.notNull(order, SysTipsException.class, "查询不到订单 orderId:"
		+ orderId);
	AgAssert.isTrue(order.getUserId() == getThreadLocalUserId(),
		SysTipsException.class, "不能操作别人的订单.");
	OrderFlow orderFlow = orderService.getFlow(order.getType());
	// 只有未付款的订单才可以取消
	orderFlow.check(order, StylistConstants.Order.Status.WAIT_PAY);
	order.setState(StylistConstants.Order.Status.CANEL);
	orderService.updateByPrimaryKeySelective(order);
	JsonObject json = success();
	return json;
    }

    @Override
    public JsonElement refund(@RequestParam Long orderId,
	    HttpServletRequest request) {
	try {
	    orderService.refund(orderId, getThreadLocalUserId());
	    JsonObject json = success();
	    return json;
	} catch (Exception e) {
	    throw new SysTipsException("请联系客服线下退款!");
	}
    }

    @Override
    @Transactional
    public JsonElement finishService(@RequestParam Long orderId) {
	orderService.service(orderId, null, getThreadLocalUserId());
	Order order = orderService.selectByPrimaryKey(orderId);
	JsonObject json = success();
	json.addProperty(
		"finishTime",
		DateUtils.format(DateUtils.YYYY_MM_DD_HH_MM,
			new Date(order.getServerFinshTime() * 1000)));
	return json;
    }

}
